//
//  ZWPageableTableView.swift
//  EIG
//
//  Created by David on 2018/9/12.
//  Copyright © 2018年 中舞网. All rights reserved.
//

import Foundation
import UIKit
import Cartography


/**
 * 支持分页的TableView，封装了MJRefresh的处理细节
 * 注：由于空占位图的应用场景有很大的差异，所以该类不包含空占位图的处理逻辑。
 */
enum EmptyViewType {
    
}

@objc class PageableTableView: UITableView {
    
    // 分页数据
    @objc private(set) var page: Int = 0            // 当前页码
    @objc private(set) var isLastPage: Bool = true  // 最后一页标志
    @objc private(set) var numberOfRows: Int = 0    // 当前数据行数
    
    // 重新加载回调
    @objc public var loadHandler: ZWPageableLoadHandler = { _, _, _ in
        fatalError("Not implemented yet")
    }
    
    // 空展位图
    private var emptyView: UIView = {
        let label = UILabel()
        label.text = Strings.emptyDataset
        label.textAlignment = .center
        label.numberOfLines = 0
        label.font = Theme.Font.regularFont(ofSize: 14)
        label.textColor = Theme.Color.placeholderTextColor
        
        let view = UIView()
        view.addSubview(label)
        constrain(label, view, block: { v, parent in
            v.center == parent.center
            v.left == parent.left+15
            v.right == parent.right-15
        })
        return view
    }()
    
    // 更新空占位图回调
    @objc public var updateEmptyViewHandler: (Bool /* isEmpty */) -> () = { _ in  }

    override init(frame: CGRect, style: UITableView.Style) {
        super.init(frame: frame, style: style)
        commonInit()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }
    
    // 初始化下拉刷新、上拉加载更多组件
    private func commonInit() {
        let header = MJRefreshNormalHeader(refreshingTarget: self, refreshingAction: #selector(pullDown2Refresh))
        mj_header = header
        
        let footer = MJRefreshAutoNormalFooter(refreshingTarget: self, refreshingAction: #selector(pullUp2LoadMore))
        mj_footer = footer
    }
    
    // 设置mj_header、mj_footer的样式
    // 这部分设置和ZWTableView类保持一致
    override var mj_header: MJRefreshHeader! {
        didSet {
            guard let header = mj_header as? MJRefreshNormalHeader else { return }
            header.setTitle(Strings.mjPull2Refresh, for: MJRefreshState.idle)
            header.setTitle(Strings.mjRelease2Refresh, for: MJRefreshState.pulling)
            header.setTitle(Strings.mjPullRefreshing, for: MJRefreshState.refreshing)
            
            header.stateLabel.font = Theme.Font.regularFont(ofSize: 13)
            header.stateLabel.textColor = UIColor(hexString: "#999999", alpha: 1.0)
            
            header.lastUpdatedTimeLabel.isHidden = true
        }
    }
    
    override var mj_footer: MJRefreshFooter! {
        didSet {
            guard let footer = mj_footer as? MJRefreshAutoNormalFooter else { return }
            
            footer.setTitle(Strings.mjPullup2LoadMore, for: MJRefreshState.idle)
            footer.setTitle(Strings.mjPullupRefreshing, for: MJRefreshState.refreshing)
            footer.setTitle(Strings.mjPullupNoMoreData, for: MJRefreshState.noMoreData)
            
            footer.stateLabel.font = Theme.Font.regularFont(ofSize: 13)
            footer.stateLabel.textColor = UIColor(hexString: "#999999", alpha: 1.0)
            
            footer.isHidden = true
        }
    }
}

// MARK: - Private Methods

extension PageableTableView {
    
    @objc func pullDown2Refresh() {
        // 加载数据
        loadHandler(0, { [weak self] (count, isLastPage) in
            self?.page = 0
            self?.numberOfRows = max(count, 0)
            self?.isLastPage = isLastPage
            self?.onDatasetChanged {
                self?.reloadData()
            }
        }, { [weak self] (error) in
            self?.onDatasetChanged {}
        })
    }
    
    @objc func pullUp2LoadMore() {
        // 加载更多数据
        let nextPage = page+1
        loadHandler(nextPage, { [weak self] (count, isLastPage) in
            guard count > 0 else { return }
            
            let insertIndex: Int = self?.numberOfRows ?? 0
            let rows: [IndexPath] = (0..<count).map {
                return IndexPath(row: insertIndex+$0, section: 0)
            }
            self?.page = nextPage
            self?.isLastPage = isLastPage
            self?.numberOfRows += max(count, 0)
            self?.onDatasetChanged {
                self?.insertRows(at: rows, with: .automatic)
            }
        }, { [weak self] (error) in
            self?.onDatasetChanged {}
        })
    }
    
    // 数据集发生变化
    // 复位MJRefresher(s)
    private func onDatasetChanged(_ refreshHandler: @escaping () -> ()) {
        // 停止刷新
        mj_header.endRefreshing()
        mj_footer.endRefreshing()
        
        // 刷新列表
        refreshHandler()
        
        if numberOfRows == 0 {
            // 空列表状态
            mj_footer.isHidden = true
            updateEmptyViewHandler(true)
        } else {
            mj_footer.isHidden = false
            if isLastPage {
                // 没有更多状态
                noMoreData()
            }
            updateEmptyViewHandler(false)
        }
    }
}


// MARK: - Public Methods

extension PageableTableView {
    
    // 注入MJ头尾组件
    public func injectMJRefresher(headerType: MJRefreshHeader.Type?, footerType: MJRefreshFooter.Type?) {
        if let headerType = headerType {
            let header = headerType.init(refreshingTarget: self, refreshingAction: #selector(pullDown2Refresh))
            mj_header = header
        }
        
        if let footerType = footerType {
            let footer = footerType.init(refreshingTarget: self, refreshingAction: #selector(pullUp2LoadMore))
            mj_footer = footer
        }
    }
    
    // 刷新列表
    public func refresh() {
        guard !mj_header.isRefreshing else { return }
        mj_header.beginRefreshing()
    }
    
    // 显示空占位图
    public func showEmptyView(_ type: EmptyViewType) {
        addEmptyView(with: type)
        emptyView.isHidden = false
    }
    
    // 隐藏空占位图
    public func hideEmptyView() {
        emptyView.isHidden = true
    }
    
    private func addEmptyView(with type: EmptyViewType) {
        guard emptyView.superview == nil else { return }
        addSubview(emptyView)
        constrain(emptyView, self) { v, parent in
            v.edges == parent.edges
        }
    }
    
    // 处理“没有更多数据”的情况
    private func noMoreData() {
        mj_header.endRefreshing()
        if let footer = mj_footer {
            footer.isHidden = false
            footer.endRefreshingWithNoMoreData()
        }
    }
}
